package com.mario.web;

import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import org.zkoss.bind.annotation.Command;
import org.zkoss.bind.annotation.NotifyChange;
import org.zkoss.util.resource.Labels;
import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.util.GenericForwardComposer;
import org.zkoss.zul.Grid;
import org.zkoss.zul.Groupbox;
import org.zkoss.zul.Image;
import org.zkoss.zul.Label;
import org.zkoss.zul.ListModelList;
import org.zkoss.zul.Row;
import org.zkoss.zul.RowRenderer;
import org.zkoss.zul.Window;

import com.mario.domain.Product;
import com.mario.service.ProductManager;
import com.mario.util.WebConstants;

@Controller
@Scope("prototype") 
public class ProductController extends GenericForwardComposer<Window> {
	
	private static final long serialVersionUID = 1L;
	protected final static Logger logger = Logger.getLogger(ProductController.class);
	
	public static final String PRODUCTS_GRID_ID		= "productsGrid";
	public static final String PRODUCT_WINDOW_ZUL	= "/WEB-INF/zul/productDialog.zul";
	public static final String DELETE_ICON_SRC		= "/widgets/img/button/rowDelete.gif";
	public static final String EDIT_ICON_SRC		= "/widgets/img/button/rowEdit.gif";
	
	//***************************************************************
	// Attributes
	//***************************************************************
	
	@Autowired
	private ProductManager productManager;
	
	private Window window;
	private Grid grid;

	//***************************************************************
	// Getters and Setters
	//***************************************************************
	
	public ProductManager getProductManager() {
		return productManager;
	}
	
	//***************************************************************
	// Methods
	//***************************************************************

	@Override
	public void doAfterCompose(Window window) throws Exception {
		logger.info("BEGIN Do after Compose.");
		super.doAfterCompose(window);
		
		productManager.addProduct("example", 20.20);
		
		// Current Window
		this.window = window;
		
		// Products Grid
		this.grid = (Grid) window.getFellowIfAny(PRODUCTS_GRID_ID);
		this.grid.setRowRenderer(getProductsGridRowRender());
		
		refresh();
		
		logger.info("END Do after Compose.");
	}

	@Command
	@NotifyChange("products")
	public void onClick$add(){
		logger.info("BEGIN Adding Product.");
		
		Map<String, Object> parameters = new HashMap<String, Object>();
		parameters.put(WebConstants.PARENT_WINDOW, window);
		
		Window addWindow = (Window) Executions.createComponents(PRODUCT_WINDOW_ZUL, null, parameters);
		addWindow.doModal();
	}
	
	@Command
	@NotifyChange("products")
	public void onClick$enLocaleBtn(){
		logger.info("BEGIN setting English locale.");
		
		Locale selectedLocale = new Locale("en", "US");
		session.setAttribute(org.zkoss.web.Attributes.PREFERRED_LOCALE, selectedLocale);
        session.setAttribute("Demo_Locale", "en_US");
        
        // Reload the same page
        Executions.sendRedirect(null);	
	}
	
	@Command
	@NotifyChange("products")
	public void onClick$esLocaleBtn(){
		logger.info("BEGIN setting Spanish locale.");
		
		Locale selectedLocale = new Locale("es", "ES");
		session.setAttribute(org.zkoss.web.Attributes.PREFERRED_LOCALE, selectedLocale);
        session.setAttribute("Demo_Locale", "es_ES");
        execution.sendRedirect("");
	}

	public List<Product> getProducts() {
		return productManager.getProducts();
	}
	
	private void refresh() {
		grid.setModel(new ListModelList<Product>(getProducts()));
	}
	
	private RowRenderer<Product> getProductsGridRowRender() {
		return new RowRenderer<Product>() {

			public void render(Row row, final Product product, int index) throws Exception {
				
				Image removeBtn = newRemoveButton(product, index);
				Image editBtn = newEditButton(product, index);
				
				Groupbox buttonGroup = new Groupbox();
				buttonGroup.appendChild(removeBtn);
				buttonGroup.appendChild(editBtn);
				
				row.appendChild(new Label(product.getOid() + ""));
		        row.appendChild(new Label(product.getDescription()));
		        row.appendChild(new Label(product.getPrice() + ""));
		        row.appendChild(buttonGroup);
			}
		};
	}
	
	public void onProductSaved() {
		refresh();
	}
	
	private Image newRemoveButton(final Product product, int index) {
		Image imageBtn = new Image();
		imageBtn.setSrc(DELETE_ICON_SRC);
		imageBtn.setId("removeBtn" + index);
		imageBtn.setTooltiptext(Labels.getLabel("productsAdmin.productsGrid.row.removeBtn.tooltip"));
		
		imageBtn.addEventListener("onClick", new EventListener<Event>() {
			public void onEvent(Event event) throws Exception {
				logger.info("BEGIN event deleting Product.");
				productManager.deleteProduct(product.getOid());
				refresh();
			}
		});
		
		return imageBtn;
	}
	
	private Image newEditButton(final Product product, int index) {
		Image imageBtn = new Image();
		imageBtn.setSrc(EDIT_ICON_SRC);
		imageBtn.setId("editBtn" + index);
		imageBtn.setTooltiptext(Labels.getLabel("productsAdmin.productsGrid.row.editBtn.tooltip"));
		
		imageBtn.addEventListener("onClick", new EventListener<Event>() {
			public void onEvent(Event event) throws Exception {
				Map<String, Object> parameters = new HashMap<String, Object>();
				parameters.put(WebConstants.SELECTED, product);
				parameters.put(WebConstants.PARENT_WINDOW, window);
				
				Window editWindow = 
						(Window) Executions.createComponents(PRODUCT_WINDOW_ZUL, null, parameters);
				
				editWindow.doModal();
			}
		});
		
		return imageBtn;
	}
}
